package com.ccjk.beusoft.hot;

import android.content.Context;
import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.text.TextUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;

/**
 * Created by CCJK on 2017/12/19.
 */

public class HookHelper {

    public static void attach(Context context) {
        try {
            Class clazz = Class.forName("android.os.ServiceManager");
            Method getServiceMethod = clazz.getMethod("getService", new Class[]{String.class});
            getServiceMethod.setAccessible(true);
            IBinder clipboardBinder = (IBinder) getServiceMethod.invoke(null, Context.CLIPBOARD_SERVICE);



            final IBinder proxyBinder = (IBinder) Proxy.newProxyInstance(clazz.getClassLoader(), clipboardBinder.getClass().getInterfaces(), new Handler1(clipboardBinder));

            //
            Field sCacheField = clazz.getField("sCache");
            sCacheField.setAccessible(true);

            ((HashMap)sCacheField.get(null)).put(Context.CLIPBOARD_SERVICE,proxyBinder);


        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

    }

    static class Handler1 implements InvocationHandler {
          Class<?> interfaceClass;
        IBinder base;

        public Handler1(IBinder binder) {
            try {
                interfaceClass = Class.forName("android.content.IClipboard");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            this.base=binder;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            if (TextUtils.equals("queryLocalInterface", method.getName())) {
                return Proxy.newProxyInstance(base.getClass().getClassLoader(), new Class[]{interfaceClass},
                        new Handler2(base));
            }

            return method.invoke(base, args);
        }
    }

    static class Handler2 implements InvocationHandler {
        Object base;

        public Handler2(IBinder binder) {
            Class stubClass = null;
            try {
                stubClass = Class.forName("android.content.IClipboard$Stub");
                Method mehod=stubClass.getMethod("asInterface",new Class[]{IBinder.class});


                base=mehod.invoke(null,binder);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }


        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            return null;
        }
    }


}
